Heroku ConnectでSalesforceデータを簡単に読み書きする
前回では、Heroku Connectを使ってSalesforceのデータを簡単に読み出してみました。さて、Heroku ConnectはSalesforceデータの読み出しだけでなく書き込みもできますので、今回はHeroku Connectを使ってSalesforeデータの読み書きを実装してみたいと思います。
Salesforce、Heroku Connectの設定変更
前回の設定ではSalesforce => Herokuの単方向の同期設定になっているので、Salesforce <=> Herokuの双方向の同期設定に変更します。
Salesforce側の設定
Heroku Connectからの書き込みにも対応するためには、Salesforceの同期対象オブジェクト(この記事では取引先責任者(Contact))にユニークかつ外部IDに指定された項目が一つ必要です。
ここでは、取引先責任者にExternalIdという項目を追加しました。
Heroku Connect側の設定
Heroku ConnectのMappingsページにアクセスします。
All Mappingsの中からContactを選択します。
Editボタンが表示されるのでクリックします。
ここで、Database => Salesforceの「Write database updates to Salesforce using [--none--] as the unique identifier」にチェックを入れ、[--none--]のセレクトボックスにて、[ExternalId__c]を指定します。
また、Salesforce => Databaseの「Accelerate Polling」にもチェックを入れておきます。この設定によってSalesforce => Heroku Connectへのデータの同期が10分間隔のポーリングのタイミングをまたず、ほぼリアルタイムで反映されるようになります。
Heroku Connectを使った取引先責任者情報の書き込み
POSTパラメータを処理するために、Node.jsのbody-parserモジュールをインストールします。
$ npm install body-parser
./index.js
をテキストエディタで開き、次の差分を適用します。
$ git diff index.js diff --git a/index.js b/index.js index be57411..9a188bd 100644 --- a/index.js +++ b/index.js @@ -1,4 +1,9 @@ -const express = require('express') +const express = require('express'); +let bodyParser = require('body-parser'); +let app = express(); +app.use(bodyParser.urlencoded({ extended: false })); +app.use(bodyParser.json()); + const path = require('path') const PORT = process.env.PORT || 5000 @@ -8,7 +13,7 @@ const pool = new Pool({ ssl: { rejectUnauthorized: false } }); -express() +app .use(express.static(path.join(__dirname, 'public'))) .set('views', path.join(__dirname, 'views')) .set('view engine', 'ejs') @@ -25,4 +30,23 @@ express() res.send("Error " + err); } }) + .get('/db/new', (req, res) => res.render('pages/db/new')) + .post('/db/new/exec', async (req, res) => { + res.setHeader('Content-Type', 'text/plain'); + try { + console.log(req.body); + const client = await pool.connect(); + const query = { + text: 'INSERT INTO salesforce.contact (LastName, FirstName, Email) VALUES ($1, $2, $3)', + values: [req.body.LastName, req.body.FirstName, req.body.Email], + }; + await client.query(query, () => { + client.release(); + res.redirect(req.baseUrl + '/db'); + }); + } catch (err) { + console.error(err); + res.send("Error " + err); + } + }) .listen(PORT, () => console.log(`Listening on ${ PORT }`))
また、次のテンプレートを./views/pages/db/new.ejs
として保存します。
<!DOCTYPE html> <html> <head> <% include ../../partials/header.ejs %> </head> <body> <% include ../../partials/nav.ejs %> <div class="container"> <h2>New Record</h2> <form action="/db/new/exec" method="post"> <input type="text" placeholder="LastName" name="LastName"> <input type="text" placeholder="FirstName" name="FirstName"> <input type="text" placeholder="Email" name="Email"> <button type="submit">Submit</button> </form> </div> </body> </html>
行おうとしていることはシンプルで、https://<your-app-name>.herokuapp.com/db/new/
へのアクセスで新規取引先責任者作成画面を開き、フォームの入力項目としてLastName(姓)、FirstName(名)、Email(メール)を受け付け、action先として/db/new/exec
を指定しています。
フォームを実行すると./index.js
の/db/new/exec
に処理が移り、INSERT INTO salesforce.contact (LastName, FirstName, Email) VALUES ($1, $2, $3)
でフォームから受け取ったLastName、FirstName、Emailをsalesforce.contact
にINSERTすることでSalesforceへの書き込みを行っています。
書き込みを行った後はres.redirect(req.baseUrl + '/db');
でhttps://<your-app-name>.herokuapp.com/db/
(一覧画面)にリダイレクトしています。
なお、一覧画面のテンプレート./views/pages/db.ejs
に次の差分を反映して、姓名、メールの表示、そして新規作成画面へのリンクを追加しています。
diff --git a/views/pages/db.ejs b/views/pages/db.ejs index 27a5f49..4efcaec 100644 --- a/views/pages/db.ejs +++ b/views/pages/db.ejs @@ -9,11 +9,14 @@ <% include ../partials/nav.ejs %> <div class="container"> +<h2>Manupilation</h2> +<a href="/db/new">Create New</a> + <h2>Database Results</h2> <ul> <% results.forEach(function(r) { %> - <li><%= r.id %> - <%= r.name %></li> + <li><%= r.id %> - <%= r.lastname %> <%= r.firstname %> ( <%= r.email %> )</li> <% }); %> </ul>
編集が終わったらコミットしてプッシュします。
$ git add -A . $ git commit -m "add create function" -v $ git push heroku
https://<your-app-name>.herokuapp.com/db/
にブラウザでアクセスして、接続したSalesforce組織の取引先責任者情報が一覧表示されることを確認します。
Create Newのテキストリンクをクリックして、取引先責任者の作成画面が開くことを確認します。
LastName、FistName、Emailに値を指定してSubmitボタンをクリックします。 画面が一覧画面に戻り、末尾に新しい取引先責任者が追加されていることを確認します。
Salesforceにアクセスして、取引先責任者に指定したLastName、FirstName、Emailを持つ新規レコードが作成されていることを確認します。
Salesforce上からこのレコードのEmailを更新してみます。
https://<your-app-name>.herokuapp.com/db/
に再アクセスして、追加した取引先責任者のEmailが更新されていることを確認します。
取引先責任者の姓、名、メールが同期対象になっているので、Salesforce上での姓、名の更新も直ちにHeroku側に反映されます。さらに、Salesforce上での取引先責任者の追加、削除も同期されますので試してみてください。
まとめ
Heroku ConnectによってHerokuとSalesforce組織を接続し、Salesforceの取引先責任者(Contact)の情報を読み書きする方法についてみてみました。簡単にSaleforceの情報をPaaSであるHerokuで読み書きして、アプリケーションで利用できることがおわかりいただけたかと思います。
Heroku <=> Salesforce間がほぼリアルタイムで同期されますので、外部システムとSalesforceを連携させる際にHeroku Connectは有力な選択肢の一つになると思います。